home *** CD-ROM | disk | FTP | other *** search
/ Assassins - Ultimate CD Games Collection 4 / Assassins 4 (1999)(Weird Science).iso / misc / omega / source / mmove.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-02  |  6.4 KB  |  291 lines

  1. /* omega copyright (c) 1987,1988,1989 by Laurence Raphael Brothers */
  2. /* mmove.c */
  3. /* monster move functions */
  4.  
  5. #include "glob.h"
  6.  
  7.  
  8. /* like m_normal_move, but can open doors */
  9. void m_smart_move(m)
  10. struct monster *m;
  11. {
  12.   m_simple_move(m);
  13. }
  14.  
  15. /* not very smart, but not altogether stupid movement */
  16. void m_normal_move(m)
  17. struct monster *m;
  18. {
  19.   m_simple_move(m);
  20. }
  21.  
  22.  
  23. /* used by both m_normal_move and m_smart_move */
  24. void m_simple_move(m)
  25. struct monster *m;
  26. {
  27.   int dx = sign(Player.x - m->x);
  28.   int dy = sign(Player.y - m->y);
  29.  
  30.   erase_monster(m);
  31.   if (m->hp < Monsters[m->id].hp/4) {
  32.     dx = - dx;
  33.     dy = - dy;
  34.     m->movef = M_MOVE_SCAREDY;
  35.     if (m->uniqueness == COMMON) {
  36.       strcpy(Str2,"The ");
  37.       strcat(Str2,m->monstring);
  38.     }
  39.     else strcpy(Str2,m->monstring);
  40.     if (m->possessions != NULL) {
  41.       strcat(Str2," drops its treasure and flees!");
  42.       m_dropstuff(m);
  43.     }
  44.     else strcat(Str2," flees!");
  45.     mprint(Str2);
  46.     m->speed = min(2,m->speed-1);
  47.   }
  48.   if ((! m_statusp(m,HOSTILE) && !m_statusp(m, NEEDY)) || 
  49.       (Player.status[INVISIBLE] > 0)) m_random_move(m);
  50.   else {
  51.     if (m_unblocked(m,m->x+dx,m->y+dy))
  52.       movemonster(m,m->x+dx,m->y+dy);
  53.     else if (dx == 0) {
  54.       if (m_unblocked(m,m->x+1,m->y+dy))
  55.     movemonster(m,m->x+1,m->y+dy);
  56.       else if (m_unblocked(m,m->x-1,m->y+dy))
  57.     movemonster(m,m->x-1,m->y+dy);
  58.     }
  59.     
  60.     else if (dy == 0) {
  61.       if (m_unblocked(m,m->x+dx,m->y+1))
  62.     movemonster(m,m->x+dx,m->y+1);
  63.       else if (m_unblocked(m,m->x+dx,m->y-1))
  64.     movemonster(m,m->x+dx,m->y-1);
  65.     }
  66.     
  67.     else {
  68.       if (m_unblocked(m,m->x+dx,m->y))
  69.     movemonster(m,m->x+dx,m->y);
  70.       else if (m_unblocked(m,m->x,m->y+dy))
  71.     movemonster(m,m->x,m->y+dy);
  72.     }
  73.   }
  74. }
  75.  
  76.  
  77.  
  78.  
  79. void m_move_animal(m)
  80. struct monster *m;
  81. {
  82.   if (m_statusp(m,HOSTILE))
  83.     m_normal_move(m);
  84.   else m_scaredy_move(m);
  85. }
  86.  
  87.  
  88.  
  89.  
  90. /* same as simple move except run in opposite direction */
  91. void m_scaredy_move(m)
  92. struct monster *m;
  93. {
  94.   int dx = -sign(Player.x - m->x);
  95.   int dy = -sign(Player.y - m->y);
  96.   erase_monster(m);
  97.   if (Player.status[INVISIBLE]) m_random_move(m);
  98.   else {
  99.     if (m_unblocked(m,m->x+dx,m->y+dy))
  100.       movemonster(m,m->x+dx,m->y+dy);
  101.     else if (dx == 0) {
  102.       if (m_unblocked(m,m->x+1,m->y+dy))
  103.     movemonster(m,m->x+1,m->y+dy);
  104.       else if (m_unblocked(m,m->x-1,m->y+dy))
  105.     movemonster(m,m->x-1,m->y+dy);
  106.     }
  107.     
  108.     else if (dy == 0) {
  109.       if (m_unblocked(m,m->x+dx,m->y+1))
  110.     movemonster(m,m->x+dx,m->y+1);
  111.       else if (m_unblocked(m,m->x+dx,m->y-1))
  112.     movemonster(m,m->x+dx,m->y-1);
  113.     }
  114.     
  115.     else {
  116.       if (m_unblocked(m,m->x+dx,m->y))
  117.     movemonster(m,m->x+dx,m->y);
  118.       else if (m_unblocked(m,m->x,m->y+dy))
  119.     movemonster(m,m->x,m->y+dy);
  120.     }
  121.   }
  122. }
  123.  
  124.  
  125.  
  126.  
  127.  
  128.  
  129. /* for spirits (and earth creatures) who can ignore blockages because
  130.    either they are noncorporeal or they can move through stone */
  131. void m_spirit_move(m)
  132. struct monster *m;
  133. {
  134.   int dx = sign(Player.x - m->x);
  135.   int dy = sign(Player.y - m->y);
  136.   erase_monster(m);
  137.   if (m->hp < Monsters[m->id].hp/6) {
  138.     dx = -dx;
  139.     dy = -dy;
  140.   }
  141.  
  142.   if (Player.status[INVISIBLE] > 0 || !m_unblocked(m, m->x+dx, m->y+dy))
  143.     m_random_move(m);
  144.   else
  145.     movemonster(m,m->x+dx,m->y+dy);
  146. }
  147.  
  148.  
  149.   
  150. /* fluttery dumb movement */
  151. void m_flutter_move(m)
  152. struct monster *m;
  153. {
  154.   int trange,range = distance(m->x,m->y,Player.x,Player.y);
  155.   int i,tx,ty,nx=m->x,ny=m->y;
  156.   erase_monster(m);
  157.   if (Player.status[INVISIBLE] > 0) m_random_move(m);
  158.   else {
  159.     for (i=0;i<8;i++) {
  160.       tx = m->x+Dirs[0][i];
  161.       ty = m->y+Dirs[1][i];
  162.       trange = distance(tx,ty,Player.x,Player.y);
  163.       if (m->hp < Monsters[m->id].hp/6) {
  164.     if ((trange > range) && m_unblocked(m,tx,ty)) {
  165.       range = trange;
  166.       nx = tx;
  167.       ny = ty;
  168.     }
  169.       }
  170.       else if ((trange <= range) && m_unblocked(m,tx,ty)) {
  171.     range = trange;
  172.     nx = tx;
  173.     ny = ty;
  174.       }
  175.     }
  176.     movemonster(m,nx,ny);
  177.   }
  178. }
  179.  
  180.  
  181. void m_follow_move(m)
  182. struct monster *m;
  183. {
  184.   if (! m_statusp(m,HOSTILE))
  185.     m_normal_move(m);
  186.   else m_scaredy_move(m);
  187. }
  188.  
  189.  
  190.  
  191. /* allows monsters to fall into pools, revealed traps, etc */
  192. void m_confused_move(m)
  193. struct monster *m;
  194. {
  195.   int i,nx,ny,done=FALSE;
  196.   erase_monster(m);
  197.   for (i=0;((i<8)&&(! done));i++) {
  198.     nx = m->x+random_range(3)-1;
  199.     ny = m->y+random_range(3)-1;
  200.     if (unblocked(nx,ny) && 
  201.     ((nx != Player.x) || 
  202.      (ny != Player.y))) {
  203.       done = TRUE;
  204.       movemonster(m,nx,ny);
  205.     }
  206.   }
  207. }
  208.  
  209. void m_random_move(m)
  210. struct monster *m;
  211. {
  212.   int i,nx,ny,done=FALSE;
  213.   erase_monster(m);
  214.   for (i=0;((i<8)&&(! done));i++) {
  215.     nx = m->x+random_range(3)-1;
  216.     ny = m->y+random_range(3)-1;
  217.     if (m_unblocked(m,nx,ny) && 
  218.     ((nx != Player.x) || 
  219.      (ny != Player.y))) {
  220.       done = TRUE;
  221.       movemonster(m,nx,ny);
  222.     }
  223.   }
  224. }
  225.  
  226.     
  227. /* monster removed from play */
  228. void m_vanish(m)
  229. struct monster *m;
  230. {
  231.   if (m->uniqueness == COMMON) {
  232.     strcpy(Str2,"The ");
  233.     strcat(Str2,m->monstring);
  234.   }
  235.   else strcpy(Str2,m->monstring);
  236.   strcat(Str2," vanishes in the twinkling of an eye!");
  237.   mprint(Str2);
  238.   Level->site[m->x][m->y].creature = NULL;
  239.   erase_monster(m);
  240.   m->hp = -1; /* signals "death" -- no credit to payer, though */
  241. }
  242.  
  243. /* monster still in play */
  244. void m_teleport(m)
  245. struct monster *m;
  246. {
  247.   erase_monster(m);
  248.   if (m_statusp(m,AWAKE)) {
  249.     Level->site[m->x][m->y].creature = NULL;
  250.     putspot(m->x,m->y,getspot(m->x,m->y,FALSE));
  251.     findspace(&(m->x),&(m->y),-1);
  252.     Level->site[m->x][m->y].creature = m;
  253.   }
  254. }
  255.  
  256. void m_move_leash(m)
  257. struct monster *m;
  258. {
  259.   m_simple_move(m);
  260.   if (m->aux1 == 0) {
  261.     m->aux1 = m->x;
  262.     m->aux2 = m->y;
  263.   }
  264.   else if (distance(m->x,m->y,m->aux1,m->aux2) > 5) {
  265.     if (Level->site[m->aux1][m->aux2].creature != NULL) {
  266.       /* some other monster is where the chain starts */
  267.       if (Level->site[m->aux1][m->aux2].creature->uniqueness == COMMON) {
  268.     strcpy(Str1, "The ");
  269.     strcat(Str1, Level->site[m->aux1][m->aux2].creature->monstring);
  270.       }
  271.       else
  272.     strcpy(Str1, Level->site[m->aux1][m->aux2].creature->monstring);
  273.       strcat(Str1, " releases the dog's chain!");
  274.       mprint(Str1);
  275.       m->movef = M_MOVE_NORMAL;
  276.       m->aux1 = m->x;
  277.       m->aux2 = m->y;
  278.       /* otherwise, we'd lose either the dog or the other monster. */
  279.     }
  280.     else if (los_p(Player.x,Player.y,m->x,m->y)) {
  281.       mprint("You see the dog jerked back by its chain!");
  282.       plotspot(m->x, m->y, FALSE);
  283.     }
  284.     else mprint("You hear a strangled sort of yelp!");
  285.     Level->site[m->x][m->y].creature = NULL;
  286.     m->x = m->aux1;
  287.     m->y = m->aux2;
  288.     Level->site[m->x][m->y].creature = m;
  289.   }
  290. }
  291.